
#include "GLRender.h"
#include "LogUtils.h"
#include "SampleTriangle.h"
#include "SampleSquare.h"
#include "SampleCube.h"
#include "SampleCircular.h"
#include "SampleCone.h"
#include "SampleCylinder.h"
#include "SampleSphere.h"
#include "SampleLightSphere.h"
#include "SampleTexture.h"
#include "SampleTextureSphere.h"

const int SAMPLE_TYPE = 200;

const int SAMPLE_TYPE_KEY_TRIANGLE = 0;//三角形
const int SAMPLE_TYPE_KEY_SQUARE = 1;//正方形/長方形
const int SAMPLE_TYPE_KEY_CUBE = 2;//正方體
const int SAMPLE_TYPE_KEY_CIRCULAR = 3;//圓形
const int SAMPLE_TYPE_KEY_CONE = 4;//圆锥
const int SAMPLE_TYPE_KEY_CYLINDER = 5;//圆柱
const int SAMPLE_TYPE_KEY_SPHERE = 6;//球体
const int SAMPLE_TYPE_KEY_LIGHTSPHERE = 7;//带光源球体
const int SAMPLE_TYPE_KEY_TEXTURE = 8;//纹理贴图
const int SAMPLE_TYPE_KEY_TEXTURE_SPERE = 9;//球体纹理贴图

//const int SAMPLE_TYPE_KEY_TEXTURE_MAP = 2;
//const int SAMPLE_TYPE_KEY_YUV_TEXTURE_MAP = 3;
//const int SAMPLE_TYPE_KEY_VAO = 4;

GLRender *GLRender::m_pContext = nullptr;

GLRender::GLRender() {
    m_Sample = new SampleTriangle();
}

GLRender::~GLRender() {
    if (m_Sample) {
        delete m_Sample;
        m_Sample = nullptr;
    }

}


void GLRender::SetParamsInt(int paramType, int value) {
    LOGCATE("GLRender::SetParamsInt paramType = %d, value = %d", paramType, value);
    if (m_Sample) {
        delete m_Sample;
        m_Sample = nullptr;
    }

    if (paramType == SAMPLE_TYPE) {
        switch (value) {
            case SAMPLE_TYPE_KEY_TRIANGLE:
                m_Sample = new SampleTriangle();
                m_Sample->setParentViewSize(m_ParentViewWidth, m_ParentViewHeight);
                break;
            case SAMPLE_TYPE_KEY_SQUARE:
                m_Sample = new SampleSquare();
                m_Sample->setParentViewSize(m_ParentViewWidth, m_ParentViewHeight);
                break;
            case SAMPLE_TYPE_KEY_CUBE:
                m_Sample = new SampleCube();
                m_Sample->setParentViewSize(m_ParentViewWidth, m_ParentViewHeight);
                break;
            case SAMPLE_TYPE_KEY_CIRCULAR:
                m_Sample = new SampleCircular();
                m_Sample->setParentViewSize(m_ParentViewWidth, m_ParentViewHeight);
                break;
            case SAMPLE_TYPE_KEY_CONE:
                m_Sample = new SampleCone();
                m_Sample->setParentViewSize(m_ParentViewWidth, m_ParentViewHeight);
                break;
            case SAMPLE_TYPE_KEY_CYLINDER:
                m_Sample = new SampleCylinder();
                m_Sample->setParentViewSize(m_ParentViewWidth, m_ParentViewHeight);
                break;
            case SAMPLE_TYPE_KEY_SPHERE:
                m_Sample = new SampleSphere();
                m_Sample->setParentViewSize(m_ParentViewWidth, m_ParentViewHeight);
                break;
            case SAMPLE_TYPE_KEY_LIGHTSPHERE:
                m_Sample = new SampleSphere();
                m_Sample->setParentViewSize(m_ParentViewWidth, m_ParentViewHeight);
                break;
            case SAMPLE_TYPE_KEY_TEXTURE:
                m_Sample = new SampleTexture();
                m_Sample->setParentViewSize(m_ParentViewWidth, m_ParentViewHeight);
                break;
            case SAMPLE_TYPE_KEY_TEXTURE_SPERE:
                m_Sample = new SampleTextureSphere();
                m_Sample->setParentViewSize(m_ParentViewWidth, m_ParentViewHeight);
                break;

                // add here

            default:
                break;
        }
    }

}

void GLRender::SetImageData(int format, int width, int height, uint8_t *pData) {
    LOGCATE("GLRender::SetImageData format=%d, width=%d, height=%d, pData=%p", format, width,
            height, pData);
    NativeImage nativeImage;
    nativeImage.format = format;
    nativeImage.width = width;
    nativeImage.height = height;
    nativeImage.ppPlane[0] = pData;

    switch (format) {
        case IMAGE_FORMAT_NV12:
        case IMAGE_FORMAT_NV21:
            nativeImage.ppPlane[1] = nativeImage.ppPlane[0] + width * height;
            break;
        case IMAGE_FORMAT_I420:
            nativeImage.ppPlane[1] = nativeImage.ppPlane[0] + width * height;
            nativeImage.ppPlane[2] = nativeImage.ppPlane[1] + width * height / 4;
            break;
        default:
            break;
    }

    if (m_Sample) {
        m_Sample->LoadImage(&nativeImage);
    }

}

void GLRender::OnSurfaceCreated() {
    LOGCATE("GLRender::OnSurfaceCreated");
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    if (m_Sample) {
        m_Sample->OnSurfaceCreated();
    }
}

void GLRender::OnSurfaceChanged(int width, int height) {
    LOGCATE("GLRender::OnSurfaceChanged [w, h] = [%d, %d]", width, height);
    m_ParentViewWidth = width;
    m_ParentViewHeight = height;
    m_ratio = (float)m_ParentViewWidth / height;
    if (m_Sample) {
        m_Sample->OnSurfaceChanged(m_ParentViewWidth, m_ParentViewHeight);
    }
    glViewport(0, 0, width, height);
}

void GLRender::OnDrawFrame() {
    LOGCATE("GLRender::OnDrawFrame");
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    if (m_Sample) {
        m_Sample->Init();
        m_Sample->Draw();
        m_Sample->Destroy();
    }
}

GLRender *GLRender::GetInstance() {
    LOGCATE("GLRender::GetInstance");
    if (m_pContext == nullptr) {
        m_pContext = new GLRender();
    }
    return m_pContext;
}

void GLRender::DestroyInstance() {
    LOGCATE("GLRender::DestroyInstance");
    if (m_pContext) {
        delete m_pContext;
        m_pContext = nullptr;
    }

}